(define-syntax let-match
  (syntax-rules ()
    ((_ i "aux" bnd () m . body)
     (let bnd . body))
    ((let-match i "aux" bnd (#f . vars) m . body)
     (let-match (+ i 1) "aux" bnd vars m . body))
    ((let-match i "aux" bnd (v . vars) m . body)
     (let-match (+ i 1) "aux" ((v (match:substring m i)) . bnd) vars m . body))
    ((_ match-exp mvars . body)
       (let ((m match-exp))
         (let-match 0 "aux" () mvars m . body)))))

(define-syntax if-match
  (syntax-rules ()
    ((_ match-exp mvars on-match no-match)
     (let ((m match-exp))
       (if m
           (let-match mvars on-match)
           no-match)))))

(define-syntax match-cond
  (syntax-rules (test else)
    ((match-cond) (cond))
    ((match-cond "aux" (pclause ...) (test . pclause2) clause ...)
     (match-cond "aux" (pclause ... pclause2) clause ...))
    ((match-cond "aux" (pclause ...) (else . eclause) clause ...)
     (match-cond "aux" (pclause ... (else . eclause)) clause ...))
    ((match-cond "aux" (pclause ...) (match-exp mvars body ...) clause ...)
     (match-cond "aux" (pclause ... (match-exp => (lambda (m) (let-match m mvars body ...)))) clause ...))
    ;; End of processing
    ((match-cond "aux" (pclause ...)) (cond pclause ...))
    ;; Start
    ((match-cond clause ...) (match-cond "aux" () clause ...))))
